using System;
using PingPong.GameEngine.Components;
using System.Collections.Generic;
using System.Linq;

namespace PingPong.GameEngine
{

	public class Session
	{
		#region Members

		/// <summary>
		/// The players.
		/// </summary>
		private Lazy<List<Player>> players;

		/// <summary>
		/// The player affinities.
		/// </summary>
		private Lazy<List<PlayerAffinity>> playerAffinities;/// 

		#endregion

		#region Properties

		/// <summary>
		/// Gets the players.
		/// </summary>
		/// <value>The players.</value>
		public IEnumerable<Player> Players
		{
			get
			{
				return this.players.Value;
			}
		}

		/// <summary>
		/// Gets the player affinities.
		/// </summary>
		/// <value>The player affinities.</value>
		public IEnumerable<PlayerAffinity> PlayerAffinities
		{
			get
			{
				return this.playerAffinities.Value;
			}
		}

		#endregion

		#region Constructors

		/// <summary>
		/// Initializes a new instance of the <see cref="PingPong.GameEngine.Session"/> class.
		/// </summary>
		public Session()
		{
			this.players = new Lazy<List<Player>>(() => new List<Player>());
			this.playerAffinities = new Lazy<List<PlayerAffinity>>(() => new List<PlayerAffinity>());
		}

		#endregion

		#region Methods

		/// <summary>
		/// Adds the player.
		/// </summary>
		/// <returns>The player.</returns>
		/// <param name="name">Name.</param>
		public Session AddPlayer(string name)
		{
			return AddPlayer(new Player().SetName(name));
		}

		/// <summary>
		/// Adds the player.
		/// </summary>
		/// <returns>The player.</returns>
		/// <param name="player">Player.</param>
		public Session AddPlayer(Player player)
		{
			this.players.Value.Add(player);
			return this;
		}

		/// <summary>
		/// Adds the player affinity.
		/// </summary>
		/// <returns>The player affinity.</returns>
		/// <param name="playerAffinity">Player affinity.</param>
		public Session AddPlayerAffinity(PlayerAffinity playerAffinity)
		{
			this.playerAffinities.Value.Add(playerAffinity);
			return this;
		}

		/// <summary>
		/// Adds the player affinity.
		/// </summary>
		/// <returns>The player affinity.</returns>
		/// <param name="player">Player.</param>
		/// <param name="preference">Preference.</param>
		public Session AddPlayerAffinity(Player player, Player preference)
		{
			return AddPlayerAffinity(new PlayerAffinity().SetFirstPlayer(player).SetSecondPlayer(preference));
		}

		#endregion
	}
}

